package org.qiqi.edu.utils.easyquery;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author qiqiang
 * @date 2019-02-16
 */
public class QueryUtils {
    public static <T> List<T> findMatch(T condition, JpaSpecificationExecutor<T> executor) {
        return executor.findAll(specification(condition));
    }

    private static <T> Specification<T> specification(T condition) {
        return (root, query, criteriaBuilder) -> {
            //查询条件
            List<Predicate> conditions = new ArrayList<>();
            //获取要查询的字段
            Field[] fields = FieldUtils.getFieldsWithAnnotation(condition.getClass(), EQField.class);
            try {
                for (Field field : fields) {
                    EQField eqField = field.getAnnotation(EQField.class);
                    //String查询
                    if (String.class.equals(field.getType())) {
                        //获取要匹配的值
                        Path<String> fieldName = root.get(field.getName());
                        Object value = PropertyUtils.getProperty(condition, field.getName());
                        if (value == null || StringUtils.isBlank(value.toString()) || fieldName == null) {
                            continue;
                        }
                        if (EQCondition.equal.equals(eqField.conditions()[0])) {
                            conditions.add(criteriaBuilder.equal(fieldName, value));
                        } else if (EQCondition.like.equals(eqField.conditions()[0])) {
                            conditions.add(criteriaBuilder.like(fieldName, "%" + value + "%"));
                        } else if (EQCondition.preLike.equals(eqField.conditions()[0])) {
                            conditions.add(criteriaBuilder.like(fieldName, "%" + value));
                        } else if (EQCondition.postLike.equals(eqField.conditions()[0])) {
                            conditions.add(criteriaBuilder.like(fieldName, value + "%"));
                        }
                        continue;
                    }
                    //日期查询
                    if (Date.class.equals(field.getType())) {
                        continue;
                    }
                    //数字查询
                    if (Integer.class.equals(field.getType()) || Long.class.equals(field.getType())) {
                        continue;
                    }
                }
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                e.printStackTrace();
            }
            Predicate[] pre = new Predicate[conditions.size()];
            return query.where(conditions.toArray(pre)).getRestriction();
        };
    }
}
